#ifndef HASHSALT_H
#define HASHSALT_H

/**
 * 加盐哈希算法实现
 */ 
#include <iostream>
#include <hash_map>
#include <unordered_map>
#include <string>

#include <openssl/sha.h>
#include <openssl/crypto.h>
#include <openssl/rand.h>

using std::cout;
using std::endl;
using std::string;

class salt_hash{
public:
    salt_hash(string passwd):m_SHA256(){
        m_SHA256 = toSHA256(passwd);
    }

    salt_hash(){

    }
    string toSHA256(string str_){
        //将输入的密码转为SHA256
        string& str=str_;
        char buf[2];
        unsigned char hash[SHA256_DIGEST_LENGTH];
        SHA256_CTX sha256;
        SHA256_Init(&sha256);
        SHA256_Update(&sha256,str.c_str(),str.size());
        SHA256_Final(hash,&sha256);
        string res="";
        for(int i=0;i<SHA256_DIGEST_LENGTH;++i){
            sprintf(buf,"%02x",hash[i]);//"%x"十六进制
            res+=buf;
        }
        return res;
    }

    void setSalt(string str){
        this->m_salt=str;
    }

    //返回一个随机盐值
    string randSalt(){
        srand(time(0));
        int key = rand();
        return toSHA256(std::to_string(key));
    }

    string getSHA256()const{
        return this->m_SHA256;
    }

    string getSalt()const{
        return m_salt;
    }

    //取回加盐哈希，这里的做法是将已经哈希的密码字符串末尾拼接上盐值，再哈希一遍
    string getSalt_hash(){
        if(m_salt_hash=="")
            m_salt_hash=toSHA256(m_SHA256.append(m_salt));
        return m_salt_hash;
    }

private:
    string m_SHA256; //哈希值
    string m_salt; //盐
    string m_salt_hash; //最终加了盐的哈希
};

#endif